import React, { forwardRef, useCallback, useImperativeHandle, useRef, useState } from 'react';
import classnames from 'classnames';

export interface InputProps {
  placeholder?: string,
  size?: string,
  value?: string,
  defaultValue?: string,
  className?: string,
  allowClear?: boolean,
  style?: React.CSSProperties,
  onChange?: (evt: React.ChangeEvent) => void, 
}

const Input = forwardRef((props: InputProps, cref): JSX.Element => {

  const {
    placeholder = '',
    size = 'md',
    defaultValue = '',
    value,
    className = '',
    style,
    allowClear = false,
    onChange,
  } = props;

  const classNames = classnames({
    "mute-input-basic": true,
    "mute-input-basic-lg": size === 'lg',
    "mute-input-basic-sm": size === 'sm',
  });

  const ref = useRef<HTMLInputElement>(null!);
  const [val, setVal] = useState<string>(value!);

  useImperativeHandle(cref, () => {
    ref.current.value = val === undefined ? defaultValue : val;
    return ref.current;
  }, [val, defaultValue]);
  
  const handleChange = useCallback((evt: any) => {
    queueMicrotask(() => {
      onChange && onChange(evt);   
      setVal(evt.target.value);
    })
  }, [onChange]);

  const handleClear = useCallback(() => {
    ref.current.value = '';
    ref.current.focus();
    setVal('');
  }, []);

  return (
    <div className="mute-input-basic-wrapper">
      {
        allowClear && (<span onClick={handleClear} style={{display: val ? "block" :"none"}} className="mute-input-clear">X</span>)
      }
      <input
        style={style}
        className={classNames + ' ' + className}
        type="text"
        placeholder={placeholder}
        defaultValue={defaultValue}
        onChange={handleChange}
        ref={ref}
      />
    </div>
  )
});

export default Input;